/*==============================================================*/
/* VIREMENT CLIENT                                              */
/*==============================================================*/
/*
procedure qui va faire le virement intraclient (entre les propres comptes d'un client) 
donc executable par le client a partir de son interface
*/
  -- valeur toujours positif !!!
CREATE OR REPLACE PROCEDURE virement_CLIENT
       (
	   -- fait un virement dans 2 comptes du meme client
	   -- le responsable de cette operation est le client .
       --Table Produit
       numProduit1         INTEGER,
       numProduit2         INTEGER,
	   -- valeur toujours positif !!!
	   valeur              INTEGER,
	   motif               VARCHAR
       )
IS
       nbre_resultat_cas1 integer := 0;
       nbre_resultat_cas2 integer := 0;
	   verfier_comtes_meme_personne INTEGER;
	   verfier_comtes_meme_personne2 INTEGER;
	   solde_moins_valeur INTEGER := 0;
	   decouvert_autorise INTEGER := 0;
BEGIN
     -- Il n y a que 4 cas,
	 -- Compte Ordinaire vers Livret Epargne
	 -- et le contraire
	 -- 2 Comptes Ordinaires
	 -- 2 comptes Epargne

	 
		-- on verifie que les 2 personnes sont les memes .------------------------
		SELECT numPersonne 
		INTO verfier_comtes_meme_personne
		FROM Client
		WHERE numpersonne
		in (SELECT numClient FROM Produit WHERE numProduit=Numproduit1) ;
		
		SELECT numPersonne
		INTO verfier_comtes_meme_personne2 
		FROM Client
		WHERE numpersonne 
		in (SELECT numClient FROM Produit WHERE numProduit=Numproduit2) ;
		
		IF (verfier_comtes_meme_personne<>verfier_comtes_meme_personne2)
		THEN
			raise_application_error (-20004 ,'Le Virement est impossible: Les 2 personnes sont differentes');
		END IF;
		-- fin verification que les 2 personnes sont les memes--------------------
		
	    -- on verifie que la valeur est positive------------------------------------
		IF (valeur<=0)
		THEN
			raise_application_error (-20005 ,'Le Virement est impossible: La valeur doit etre positive !');
		END IF;
		-- fin verification valeur > 0

		-- on verifie que les produits sont differents !
		IF (numProduit1=numProduit2)
		THEN
			raise_application_error (-20006 ,'Le Virement est impossible: Les Produits ne peuvent pas etre les memes !');
		END IF;
		-- fin verification produits differents
	 
	 
	 ---------------------------------
	 -- 1er cas :
	SELECT count(*) INTO nbre_resultat_cas1 FROM compte_ordinaire WHERE numProduit=Numproduit1 ;
	SELECT count(*) INTO nbre_resultat_cas2 FROM livret_epargne WHERE numProduit=Numproduit2 ;
	
	
	 -- les comptes existent et la personne est la meme
	 -- Numproduit1 est dans compte_ordinaire
	 -- Numproduit2 est dans livret_epargne
     IF (nbre_resultat_cas1<>0 AND nbre_resultat_cas2<>0)
        THEN
		
		-- test si le decouvert autorise est depasse :
		-- solde_moins_valeur doit etre superieur a 0-decouvert_autorise
		SELECT solde 
		INTO solde_moins_valeur
		FROM compte 
		WHERE numProduit=Numproduit1 ;
		-- on a le nouveau solde dans solde_moins_valeur
		solde_moins_valeur := solde_moins_valeur - valeur ;
		-- test de deciouvert
		SELECT decouvertautorise 
		INTO decouvert_autorise
		FROM compte_ordinaire 
		WHERE numProduit=Numproduit1 ;
			-- si le decouvert est depasse:
			IF (solde_moins_valeur<(0-decouvert_autorise))
			THEN
				raise_application_error (-20007 ,'Le Virement est impossible: le decouvert de'||decouvert_autorise||' serait depasse. ');
			END IF;
		
				-- on update les 2
				UPDATE compte SET solde = (solde-valeur) WHERE numProduit = Numproduit1;
				UPDATE compte SET solde = (solde+valeur) WHERE numProduit = Numproduit2;
				-- on log l operation dans operation
				INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			               VALUES (seqnumOperation.nextval, numProduit1, numProduit2, NULL, motif, SYSDATE, valeur,'debit') ;
            		        INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			               VALUES (seqnumOperation.nextval, numProduit2, numProduit1, NULL, motif, SYSDATE, valeur,'credit') ;
	 END IF; -- nbre resultats <>0

	 
	 
	 
	 
	 --------------
	 -- 2eme cas :
	SELECT count(*) INTO nbre_resultat_cas1 FROM livret_epargne WHERE numProduit=Numproduit1 ;
	SELECT count(*) INTO nbre_resultat_cas2 FROM compte_ordinaire WHERE numProduit=Numproduit2 ;

	
	 -- les comptes existent et la personne est la meme
	 -- il ne peut pas a ce moment avoir de depassement de decouvert (pas dans la specification)
     IF (nbre_resultat_cas1<>0 AND nbre_resultat_cas2<>0 )
        THEN
			
			-- on update les 2
			UPDATE compte SET solde = (solde+valeur) WHERE numProduit = Numproduit2;
			UPDATE compte SET solde = (solde-valeur) WHERE numProduit = Numproduit1;
			-- on log l operation dans operation
			INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			   VALUES (seqnumOperation.nextval, numProduit1, numProduit2, NULL, motif, SYSDATE, valeur,'debit') ;
            		INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			   VALUES (seqnumOperation.nextval, numProduit2, numProduit1, NULL, motif, SYSDATE, valeur,'credit') ;
	 END IF;

	 
	 
	 
	 
	 
	 
	 
	 ---------------------------------------
	 -- 3eme cas : 2 comptes ordinaires :
	SELECT count(*) INTO nbre_resultat_cas1 FROM compte_ordinaire WHERE numProduit=Numproduit1 ;
	SELECT count(*) INTO nbre_resultat_cas2 FROM compte_ordinaire WHERE numProduit=Numproduit2 ;
	 -- les comptes existent et la personne est la meme
	 -- il ne peut pas a ce moment avoir de depassement de decouvert (pas dans la specification)
     IF (nbre_resultat_cas1<>0 AND nbre_resultat_cas2<>0 )
     THEN

		-- test si le decouvert autorise est depasse :
		-- solde_moins_valeur doit etre superieur a 0-decouvert_autorise
		SELECT solde 
		INTO solde_moins_valeur
		FROM compte
		WHERE numProduit=Numproduit1 ;
		-- on a le nouveau solde dans solde_moins_valeur
		solde_moins_valeur := solde_moins_valeur - valeur ;
		-- test de deciouvert
		SELECT decouvertautorise 
		INTO decouvert_autorise
		FROM compte_ordinaire 
		WHERE numProduit=Numproduit1 ;
			-- si le decouvert est depasse:
			IF (solde_moins_valeur<(0-decouvert_autorise))
			THEN
				raise_application_error (-20008 ,'Le Virement est impossible: le decouvert de'||decouvert_autorise||' serait depasse. ');
			END IF;
		
				-- on update les 2
				UPDATE compte SET solde = (solde-valeur) WHERE numProduit = Numproduit1;
				UPDATE compte SET solde = (solde+valeur) WHERE numProduit = Numproduit2;
				-- on log l operation dans operation
				INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			   VALUES (seqnumOperation.nextval, numProduit1, numProduit2, NULL, motif, SYSDATE, valeur,'debit') ;
            		        INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			   VALUES (seqnumOperation.nextval, numProduit2, numProduit1, NULL, motif, SYSDATE, valeur,'credit') ;
	  END IF;
	
	
	
	
	
	 ---------------------------------------
	 -- 4eme cas : 2 Livrets Epargne :
	SELECT count(*) INTO nbre_resultat_cas1 FROM livret_epargne WHERE numProduit=Numproduit1 ;
	SELECT count(*) INTO nbre_resultat_cas2 FROM livret_epargne WHERE numProduit=Numproduit2 ;
	 -- les comptes existent et la personne est la meme
	 -- il ne peut pas a ce moment avoir de depassement de decouvert (pas dans la specification)
     IF (nbre_resultat_cas1<>0 AND nbre_resultat_cas2<>0 )
     THEN
				-- on update les 2
				UPDATE compte SET solde = (solde-valeur) WHERE numProduit = Numproduit1;
				UPDATE compte SET solde = (solde+valeur) WHERE numProduit = Numproduit2;
				-- on log l operation dans operation
				INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			   VALUES (seqnumOperation.nextval, numProduit1, numProduit2, NULL, motif, SYSDATE, valeur,'debit') ;
            		        INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			   VALUES (seqnumOperation.nextval, numProduit2, numProduit1, NULL, motif, SYSDATE, valeur,'credit') ;
	  END IF;
	
	
END virement_CLIENT;
/


/*==============================================================*/
/* VIREMENT EMPLOYE                                             */
/*==============================================================*/
/*
procedure qui va faire le virement inter-client
donc executable par l'employe uniquement
*/

  -- valeur toujours positif !!!
CREATE OR REPLACE PROCEDURE virement_EMPLOYE
       (
	   -- fait un virement dans 2 comptes quelconques
	   -- le responsable de cette operation estun employe .
	   -- Table employe
	   numEmploye          INTEGER,
       --Table Produit
       numProduit1         INTEGER,
       numProduit2         INTEGER,
	   -- valeur toujours positif !!!
	   valeur              INTEGER,
	   motif               VARCHAR
       )
IS
       nbre_resultat_cas1 integer := 0;
       nbre_resultat_cas2 integer := 0;
	   solde_moins_valeur INTEGER := 0;
	   decouvert_autorise INTEGER := 0;
BEGIN
     -- Il n y a que 4 cas,
	 -- Compte Ordinaire vers Livret Epargne
	 -- et le contraire
	 -- 2 Comptes Ordinaires
	 -- 2 comptes Epargne


		
	    -- on verifie que la valeur est positive------------------------------------
		IF (valeur<=0)
		THEN
			raise_application_error (-20009 ,'Le Virement est impossible: La valeur doit etre positive !');
		END IF;
		-- fin verification valeur > 0
	 
		-- on verifie que les produits sont differents !
		IF (numProduit1=numProduit2)
		THEN
			raise_application_error (-20010 ,'Le Virement est impossible: Les Produits ne peuvent pas etre les memes !');
		END IF;
		-- fin verification produits differents
	SELECT count(*) INTO nbre_resultat_cas1 FROM EMPLOYE WHERE numPersonne=numEmploye ;
	IF (nbre_resultat_cas1=0)
	THEN
				raise_application_error (-20011 ,'Employe ' || numEmploye || ' inexistant');
	END IF;
	 
	 ---------------------------------
	 -- 1er cas :
	SELECT count(*) INTO nbre_resultat_cas1 FROM compte_ordinaire WHERE numProduit=Numproduit1 ;
	SELECT count(*) INTO nbre_resultat_cas2 FROM livret_epargne WHERE numProduit=Numproduit2 ;
	
	
	 -- les comptes existent et la personne est la meme
	 -- Numproduit1 est dans compte_ordinaire
	 -- Numproduit2 est dans livret_epargne
     IF (nbre_resultat_cas1<>0 AND nbre_resultat_cas2<>0)
        THEN
		
		-- test si le decouvert autorise est depasse :
		-- solde_moins_valeur doit etre superieur a 0-decouvert_autorise
		SELECT solde 
		INTO solde_moins_valeur
		FROM compte
		WHERE numProduit=Numproduit1 ;
		-- on a le nouveau solde dans solde_moins_valeur
		solde_moins_valeur := solde_moins_valeur - valeur ;
		-- test de deciouvert
		SELECT decouvertautorise 
		INTO decouvert_autorise
		FROM compte_ordinaire 
		WHERE numProduit=Numproduit1 ;
			-- si le decouvert est depasse:
			IF (solde_moins_valeur<(0-decouvert_autorise))
			THEN
				raise_application_error (-20012 ,'Le Virement est impossible: le decouvert de'||decouvert_autorise||' serait depasse. ');
			END IF;
		
				-- on update les 2
				UPDATE compte SET solde = (solde-valeur) WHERE numProduit = Numproduit1;
				UPDATE compte SET solde = (solde+valeur) WHERE numProduit = Numproduit2;
				-- on log l operation dans operation
				INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			               VALUES (seqnumOperation.nextval, numProduit1, numProduit2, numEmploye, motif, SYSDATE, valeur,'debit') ;
            		        INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			               VALUES (seqnumOperation.nextval, numProduit2, numProduit1, numEmploye, motif, SYSDATE, valeur,'credit') ;
	 END IF; -- nbre resultats <>0

	 
	 
	 
	 
	 --------------
	 -- 2eme cas :
	SELECT count(*) INTO nbre_resultat_cas1 FROM livret_epargne WHERE numProduit=Numproduit1 ;
	SELECT count(*) INTO nbre_resultat_cas2 FROM compte_ordinaire WHERE numProduit=Numproduit2 ;

	
	 -- les comptes existent et la personne est la meme
	 -- il ne peut pas a ce moment avoir de depassement de decouvert (pas dans la specification)
     IF (nbre_resultat_cas1<>0 AND nbre_resultat_cas2<>0 )
        THEN
			
			-- on update les 2
			UPDATE compte SET solde = (solde+valeur) WHERE numProduit = Numproduit2;
			UPDATE compte SET solde = (solde-valeur) WHERE numProduit = Numproduit1;
			-- on log l operation dans operation
			INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			   VALUES (seqnumOperation.nextval, numProduit1, numProduit2, numEmploye, motif, SYSDATE, valeur,'debit') ;
            		INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			   VALUES (seqnumOperation.nextval, numProduit2, numProduit1, numEmploye, motif, SYSDATE, valeur,'credit') ;
	 END IF;

	 
	 
	 
	 
	 
	 
	 
	 ---------------------------------------
	 -- 3eme cas : 2 comptes ordinaires :
	SELECT count(*) INTO nbre_resultat_cas1 FROM compte_ordinaire WHERE numProduit=Numproduit1 ;
	SELECT count(*) INTO nbre_resultat_cas2 FROM compte_ordinaire WHERE numProduit=Numproduit2 ;
	 -- les comptes existent et la personne est la meme
	 -- il ne peut pas a ce moment avoir de depassement de decouvert (pas dans la specification)
     IF (nbre_resultat_cas1<>0 AND nbre_resultat_cas2<>0 )
     THEN

		-- test si le decouvert autorise est depasse :
		-- solde_moins_valeur doit etre superieur a 0-decouvert_autorise
		SELECT solde 
		INTO solde_moins_valeur
		FROM compte
		WHERE numProduit=Numproduit1 ;
		-- on a le nouveau solde dans solde_moins_valeur
		solde_moins_valeur := solde_moins_valeur - valeur ;
		-- test de deciouvert
		SELECT decouvertautorise 
		INTO decouvert_autorise
		FROM compte_ordinaire 
		WHERE numProduit=Numproduit1 ;
			-- si le decouvert est depasse:
			IF (solde_moins_valeur<(0-decouvert_autorise))
			THEN
				raise_application_error (-20013 ,'Le Virement est impossible: le decouvert de'||decouvert_autorise||' serait depasse. ');
			END IF;
		
				-- on update les 2
				UPDATE compte SET solde = (solde-valeur) WHERE numProduit = Numproduit1;
				UPDATE compte SET solde = (solde+valeur) WHERE numProduit = Numproduit2;
				-- on log l operation dans operation
				INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			   VALUES (seqnumOperation.nextval, numProduit1, numProduit2, numEmploye, motif, SYSDATE, valeur,'debit') ;
            		        INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			   VALUES (seqnumOperation.nextval, numProduit2, numProduit1, numEmploye, motif, SYSDATE, valeur,'credit') ;
	  END IF;
	
	
	
	
	
	 ---------------------------------------
	 -- 4eme cas : 2 Livrets Epargne :
	SELECT count(*) INTO nbre_resultat_cas1 FROM livret_epargne WHERE numProduit=Numproduit1 ;
	SELECT count(*) INTO nbre_resultat_cas2 FROM livret_epargne WHERE numProduit=Numproduit2 ;
	 -- les comptes existent et la personne est la meme
	 -- il ne peut pas a ce moment avoir de depassement de decouvert (pas dans la specification)
     IF (nbre_resultat_cas1<>0 AND nbre_resultat_cas2<>0 )
     THEN
				-- on update les 2
				UPDATE compte SET solde = (solde-valeur) WHERE numProduit = Numproduit1;
				UPDATE compte SET solde = (solde+valeur) WHERE numProduit = Numproduit2;
				-- on log l operation dans operation
				INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			   VALUES (seqnumOperation.nextval, numProduit1, numProduit2, numEmploye, motif, SYSDATE, valeur,'debit') ;
            		        INSERT INTO operation (NUMOP, NUMPRODUIT, NUMPRODUITDESTINATAIRE, NUMEMPLOYE, MOTIFOP, DATEOP, MONTANTOP, TYPEOP)
			   VALUES (seqnumOperation.nextval, numProduit2, numProduit1, numEmploye, motif, SYSDATE, valeur,'credit') ;
	  END IF;

	
END virement_EMPLOYE;
/